#include<iostream>
#include<vector>
#include<string>
using namespace std;

// // 外卖小哥
// class Delivery_person
// {
//     string _name;           // 姓名
//     string _id;             // 身份证
//     string _address;        // 地址
//     long long _telephone;   // 手机号
//     // ...
// };

// // 商家
// class Merchant
// {
//     string _name;           // 姓名
//     string _id;             // 身份证
//     string _address;        // 地址
//     long long _telephone;   // 手机号
//     // ...
// };

// // 顾客
// class Customer
// {
//     string _name;           // 姓名
//     string _id;             // 身份证
//     string _address;        // 地址
//     long long _telephone;   // 手机号
//     // ...
// };

#if 0

class Person
{
    string _name;           // 姓名
    string _id;             // 身份证
    string _address;        // 地址
    long long _telephone;   // 手机号
public:
    void setName(const string& name) { _name = name; }
    string& getName() { return _name; }
};

//            派生类    继承方式  基类
// 外卖小哥      |         |       |
class Delivery_person : public Person
{
    // ...
};

// 商家
class Merchant : public Person
{
    // ...
};

// 顾客
class Customer : public Person
{
    // ...
};

int main()
{
    Delivery_person d;
    d.setName("张三");
    cout << d.getName() << endl << sizeof(d) << endl;

    Merchant m;
    m.setName("李四");
    cout << m.getName() << endl << sizeof(m) << endl;

    Customer c;
    c.setName("王五");
    cout << c.getName() << endl << sizeof(c) << endl;
    return 0;
}
#endif

// class A
// {
// public:
//     int _val_public = 1;
//     void _func_public() { cout << "void _func_public()" << endl; }

// protected:
//     int _val_protected = 2;
//     void _func_protected() { cout << "void _func_protected()" << endl; }

// private:
//     int _val_private = 3;
//     void _func_private() { cout << "void _func_private()" << endl; }
// };

// class B : public A
// {
// public:
//     void func_B()
//     {
//         // 子类类内部可以访问父类的protected成员
//         cout << _val_protected << endl; 
//         _func_protected(); 
//     }
// };

// int main()
// {
//     B b1;
//     // 子类外部不可访问父类的protected成员
//     cout << b1._val_protected << endl; // 编译错误
//     b1._func_protected();   // 编译错误
//     return 0;
// }

// class A
// {
// private:
//     int _val_private = 3;
//     void _func_private() { cout << "void _func_private()" << endl; }
// };


// class B : A     // 不写继承方式，默认private继承，即class B : private A
// {
// public:
//     void func_B()
//     {
//         // cout << _val_private << endl;   // 编译报错，A类的private成员变量在B类中无法访问
//         // _func_private();        // 编译报错，A类的private成员函数在B类中无法访问
//     }
// };

// // public继承
// class B : public A
// {
// public:
//     void func_B()
//     {
//         // cout << _val_private << endl;   // 编译报错，A类的private成员变量在B类中无法访问
//         // _func_private();        // 编译报错，A类的private成员函数在B类中无法访问
//     }
// };

// int main()
// {
//     B b1;
//     return 0;
// }

// class Person
// {
// protected:
//     string _name;           // 姓名
//     string _address;        // 地址
//     long long _telephone;   // 手机号
// };

// // 顾客
// class Customer : public Person
// {
// protected:
//     vector<string> _favorite; // 顾客收藏的美食

// public:
//     // 设置姓名、地址、手机
//     void set(string name, string address, long long tel)
//     {
//         _name = name, _address = address, _telephone = tel;
//     }
//     // 收藏美食
//     void add_favorite(const string& food)
//     {
//         _favorite.push_back(food);
//     }
// };

// int main()
// {
//     Customer c1;
//     c1.set("牛爷爷", "翻斗花园", 1234567);
//     c1.add_favorite("西红柿炒鸡蛋");

//     Person p;
//     p = c1; // 这里p是Person类型，c1是Customer类型，Person并没有提供Customer的构造，却可以直接赋值

//     return 0;
// }

// int main()
// {
//     int a = 10;

//     {
//         int a = 20;     // 这里的a在内部花括号里，跟上面那个a重名。两个a在不同的作用域，可以同时存在
//         cout << a << endl;     // 编译器会现在当前作用域查找，输出20
//         // 那我该如何在内部花括号里访问第一个a呢？好像不行，第一个a被隐藏了！
//     }

//     return 0;
// }

// class Person
// {
// public:	// 为了方便观察，设为public
//     string _name;           // 姓名
//     string _address;        // 地址
//     long long _telephone;   // 手机号
// };

// // 顾客
// class Customer : public Person
// {
// public:
//     string _name;   // 子类可以与父类有同名成员
//     // 子类中的_name属于Customer类域，父类中的_name属于Person类域

//     void Print_name()
//     {
//         cout << _name << endl;      // 在Customer类中访问_name，会现在当前类域查找
//         cout << Person::_name << endl;  // 若想访问父类的_name, 需指定作用域
//     }
// };

// int main()
// {
//     Customer c1;
//     c1._name = "胡图图";
//     cout << c1._name << endl;;

//     c1.Person::_name = "xxx";
//     cout <<  c1.Person::_name << endl;
//     return 0;
// }




// class A
// {
//     int _a;
// public:
//     A() { cout << "A()" << endl; }
//     A(int x) 
//         :_a(x)
//     {  cout << "A(int x)" << endl; }
// };

// class B
// {
//     int _b;
//     A _aa;
// public:
    
//     B() 
//         :_aa(5)
//     { cout << "B()" << endl; }
    
//     B(int x)
//         :_aa(x)
//     {
//         cout << "B(int x)" << endl;
//     }
// };


// class A
// {
// protected:
//     int _a;
// public:
//     A() { cout << "A()" << endl; }
//     A(int x) 
//         :_a(x)
//     {  cout << "A(int x)" << endl; }
// };

// class C
// {
//     int _c;
// public:
//     C(int c) 
//     {
//         _c = c;
//         cout << "C(int c)" << endl;
//     }
// };

// // B继承A
// class B : public A
// {
// protected:
//     int _x;
//     C _cc;  // B还有C类型的成员变量
// public:

//     B() 
//         :_cc(55)    // 初始化列表顺序是按声明的顺序来的，第一个成员变量父类成员。即使这里先写_cc的初始化，也不会第一个初始化_cc
//         ,A(10)
//     { cout << "B()" << endl; }
// };

// int main()
// {
//     B b1;
//     return 0;
// }

// class A
// {
// protected:
//     int _a;
// public:
//     A() {}
//     A(const A& a) { cout << "A(const A& a)" << endl; }
// };

// class C
// {
//     int _c;
// public:
//     C(){}
//     C(const C& c) { cout << "C(const C& c)" << endl; }
// };

// // B继承A
// class B : public A
// {
// protected:
//     int _x;
//     C _cc;  // B还有C类型的成员变量
// public:
//     B() {}

//     B(const B& b)
//         :A(b)       // 调用父类拷贝构造，切片
//         ,_cc(b._cc)
//         ,_x(b._x)
//     {
//         // cout << "B(const B& b)" << endl;
//     }
// };

// int main()
// {
//     B b1;
//     B b2(b1);
//     return 0;
// }


// class A
// {
// protected:
//     int _a;
// public:
//     A& operator= (const A& a)
//     { 
//         cout << "A& operator= (const A& a)" << endl; 
//         return *this;
//     }
// };

// class C
// {
//     int _c;
// public:
//     C& operator= (const C& c)
//     { 
//         cout << "C& operator= (const C& c)" << endl; 
//         return *this;
//     }
// };

// // B继承A
// class B : public A
// {
// protected:
//     int _x;
//     C _cc;  // B还有C类型的成员变量
// public:
//     B& operator= (const B& b)
//     {
//         A::operator=(b);    // 子类的赋值重载与父类的赋值重载同名，父类会被隐藏，需指定类域
//         _cc = b._cc;
//         _x = b._x;
//         return *this;
//     }
// };

// int main()
// {
//     B b1;
//     B b2;
//     b2 = b1;
//     return 0;
// }

// class A
// {
// protected:
//     int _a;
// public:
//     ~A() { cout << "~A()" << endl; }
// };

// class C
// {
//     int _c;
// public:
//     ~C() { cout << "~C()" << endl; }
// };

// // class D
// // {
// //     int _d;
// // public:
// //     ~D() { cout << "~D()" << endl; }
// // };

// // B继承A
// class B : public A
// {
// protected:
//     C _cc;  // B还有C类型的成员变量
//     int _x;
// public:
//     ~B()
//     {
//         A::~A();    // 显示调用父类的析构，但需要指定父类的类域。原理后面的多态会讲
//         _cc.~C();   // 自定义类型的对象显式调用其析构
//         // ~B()调用完，还会自动调用_cc与父类成员的析构
//     }
// };

// int main()
// {
//     B b1;
//     return 0;
// }


// class B; // 由于会在B类定义前用到B类，这里先声明一下

// class A
// {
// protected:
//     int _a;
// public:
//     // ~A() { cout << "~A()" << endl; }
//     friend void Print(const A& aa, const B& bb);
// };

// // B继承A
// class B : public A
// {
// protected:
//     int _b;
// };

// void Print(const A& aa, const B& bb)
// {
//     cout << aa._a << endl;  // A类把Print当朋友，Print可以访问A类private、protected成员
//     // cout << bb._b << endl;  // err，B类没把Print当朋友，Print无法访问B类private、protected成员
// }

// int main()
// {
//     A aa1;
//     B bb1;
//     Print(aa1, bb1);
//     return 0;
// }

// class Person
// {
// protected:
//     string _name;
// public:
//     static int _count;
// };

// int Person::_count = 0; // 类内的静态成员需在类外定义

// class Student : public Person
// {
// protected:
//     int id;
// };

// int main()
// {
//     Person p1;
//     cout << p1._count << endl;      // 用对象访问静态成员变量
//     cout << Person::_count << endl; // 用类域访问静态成员变量

//     Student s1;
//     s1._count = 999;         // 子类对象也可以访问到父类的静态成员变量
//     cout << s1._count << endl;
//     cout << Student::_count << endl; // 也可以用子类的类域访问

//     cout << &Person::_count << endl;
//     cout << &Student::_count << endl;
//     return 0;
// }

// class A
// {
// protected:
//     int _a;
// };

// class B
// {
// protected:
//     int _b;
// };

// class C : public A, public B
// {
// protected:
//     int _c;
// public:
//     void Print()
//     {
//         _a = _c = _b = 888;
//         cout << _a << ' ' << _b << ' ' << _c << endl;
//     }
// };

// int main()
// {
//     C cc;
//     cc.Print();
//     return 0;
// }


// 植物
class Plant
{
public: // 方便调试，这里设为public
    string _name; // 植物名
};

// 蔬菜
class Vegetable : virtual public Plant
{
protected:
    double _price;  // 单价
};

// 水果
class Fruit : virtual public Plant
{
protected:
    int _pick_date; // 采摘日期
};

// 西红柿, 继承了蔬菜类与水果类
class Tomato : public Vegetable, public Fruit
{
protected:
    int _color; // 颜色
};

int main()
{
    Tomato t;   // t里面会有两份_name，一份来自Vegetable，一份来自Fruit
    t._name = "xxx"; // 不能直接访问
    t.Vegetable::_name = "山东西红柿";
    t.Fruit::_name = "河南西红柿";
    return 0;
}